home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 4
/
FM Towns Free Software Collection 4 - Disc 1.iso
/
kxc
/
towns_os
/
pics
/
pics.c
< prev
next >
Wrap
Text File
|
1991-10-18
|
10KB
|
451 lines
/*
* PIC file saver coded by "C"
* 1989-9 ver 0.00 by Akira-Y.
* 1990.09.04 TOWNS版 Ver 0.1 by MSどす
* 1991.01.12 TOWNS版 Ver 0.21 by KXC KAROU・UOTA
* 1991.01.23 TOWNS版 Ver 0.22 by KXC KAROU・UOTA
* 1991.01.23 TOWNS版 Ver 0.23 by KXC KAROU・UOTA
*
* Ver 0.1,及び0.22で色調が落ちる障害を無
* くしました。
* MS-DOSではレイヤ0に各種グラフィックを表示後、
* コマンドライン上で、
* RUN386 PICS [X Y X' Y'] FILENAME
* と入力して下さい。
* T-MENUからは、各ローダーと組にしたバッチファイル
* で御使用下さい。
*
* 画面モード9、10、11のみで使用可能です。
* 画面サイズは仮想領域のフルサイズ(512×256)
* 迄対応しており、デフォルトのセーブ領域が、
* (0,0)-(511,255)
* となっております。
* 画面モード17の、512×512ドットモードをベー
* スにする際は、
* HS_psetm10
* HS_pointm10
* 各々のセグメントの値を書換え、
* header_write()
* 上記ルーチンのPICのヘッダフォーマットを512×
* 512迄のX6(標準PICフォーマット)とTOWN
* Sの各モード値に変更して下さい。それ以外の値は使用
* しないで下さい。
*
*
*/
pragma on ( Align_members ) ;
pragma on ( Align_all_labels ) ;
pragma on ( Align_labels ) ;
pragma on ( Align_routines ) ;
#include <stdio.h>
#include <stdlib.h>
#include <egb.h>
#define SHORT short int
#define USHORT unsigned short int
#define UCHAR unsigned char
#define LONG long
/*---------- Please rewrite --------------------------------------------*/
#define SIZE_OF_X 512 /* your screen X max */
#define SIZE_OF_Y 256 /* your screen Y max */
/*----------------------------------------------------------------------*/
#define SIZE_OF_BUFF 512*256*2 /* file write buff size
* you can change this parameter
* value limit is 1 ~ max(integer)
*/
FILE *fp ;
int bit_length, /* *buff_p effective bit length */
buff_length, /* buff rest */
x0,x1,y0,y1; /* (x0,y0)-(x1,y1) save area */
char *buff_p, /* buff's read pointer */
buff[SIZE_OF_BUFF]; /* file read buff */
struct { /* for use color cash table */
int color; /* dual LIST struct */
int next;
int prev;
} table[128];
int color_p; /*index for new color cash table*/
void diff_point_mark(), /* diff. point marking */
header_write(), /* pic file header write */
press(), /* compress routine */
press_chain(), /* chain data write */
write_length(), /* diff. point length write */
write_color(), /* color code write */
color_cash_init(), /* color cash table init. */
new_color(), /* set new color to table */
set_color(), /* change top of table */
bit_write(), /* n bits write to file */
buff_next_w(), /* pointer next and write */
buff_flush(), /* write buff flush */
error(), /* error mess type and exit */
pset() ; /* put color to graphic ram */
int point(), /* get color from graphic ram */
search_col(); /* search color code from table */
extern void HS_psetm10( int x,int y,int color ) ;
extern int HS_pointm10( int x,int y ) ;
/*
* main procedure of pic saver
*
*/
void
main(argc, argv)
int argc;
char **argv;
{
char *file;
if (argc != 2 && argc != 6) {
error("usage : pics [x y x' y'] <file>");
}
if (argc == 6) {
x0 = atoi(argv[1]);
y0 = atoi(argv[2]);
x1 = atoi(argv[3]);
y1 = atoi(argv[4]);
file = argv[5];
if (x0 > x1 || y0 > y1 || x1 >= SIZE_OF_X || y1 >= SIZE_OF_Y) {
error( "size over" ) ;
}
} else {
x0 = y0 = 0 ;
x1 = SIZE_OF_X - 1 ;
y1 = SIZE_OF_Y - 1 ;
file = argv[1] ;
}
if ( (fp = fopen(file,"wb")) == NULL ){
error("file can not open") ; /* ERROR */
}
buff_p = buff ; /* file pointer etc. initialize */
buff_length = SIZE_OF_BUFF ;
bit_length = 8 ;
color_cash_init() ; /* color cash table init. */
header_write() ; /* pic file header write */
diff_point_mark() ; /* color diff. point marking */
press() ; /* compress exec. */
buff_flush() ; /* write buff flush */
fclose( fp ) ;
}
void
diff_point_mark()
{
int x,y,c,a ;
c = 0 ; /* 1st. color = 0 */
for ( y = y0 ; y <= y1 ; y++ ) {
for ( x = x0 ; x <= x1 ; x++ ) {
if ((a = (point(x, y) & 0x7fff)) != c) {
c = a ;
pset( x,y,( c|0x8000 )); /* lsb mark */
} else {
pset( x,y,a ) ; /* lsb clr */
}
}
}
}
void
header_write()
{
bit_write( 8, (LONG)'P'); /* write ID */
bit_write( 8, (LONG)'I');
bit_write( 8, (LONG)'C');
bit_write( 8, (LONG)26 ); /* text eof */
bit_write( 8, (LONG)0 ); /* separater */
/* mode */
bit_write(16, (LONG)0x0052 ); /* TOWNS_mode */
bit_write(16, (LONG)15 ); /* color lenght */
bit_write(16, (LONG)(x1 - x0 + 1)); /* width of x */
bit_write(16, (LONG)(y1 - y0 + 1)); /* width of y */
}
void
press()
{
LONG l ; /* for diff. length */
int x, y, a;
l = 0;
for (y = y0; y <= y1; y++) {
for (x = x0; x <= x1; x++) {
++l ;
if ((a = point(x, y)) & 0x8000) {/* find mark point */
write_length(l);
write_color(a);
press_chain(x, y, a);
pset(x, y,( a&0x7fff ));
l = 0;
}
}
}
write_length(l + 1); /* end data */
bit_write(8, (LONG)0); /* オマケだけど必要 */
}
void
press_chain(x, y, c)
int x, y, c;
{
int yy, d, f;
f = 0; /* chain exist flag */
for (yy = y + 1; yy <= y1; yy++) {
if ( point(x, yy) == c) d = 2;
else if ( --x >= x0 && point(x, yy) == c) d = 1;
else if ((x += 2) <= x1 && point(x, yy) == c) d = 3;
else if ((x -= 3) >= x0 && point(x, yy) == c) d = 4;
else if ((x += 4) <= x1 && point(x, yy) == c) d = 5;
else break ;
pset(x, yy,( c&0x7fff )) ;
if (f == 0) bit_write(1, (LONG)1);
if (d == 4) bit_write(4, (LONG)2);
else if (d == 5) bit_write(4, (LONG)3);
else if (d <= 3) bit_write(2, (LONG)d);
f = 1;
}
if (f == 0) bit_write(1, (LONG)0);
else bit_write(3, (LONG)0);
}
void
write_length(n)
LONG n;
{
int a;
LONG b;
a = 1 ;
b = 4 ;
while (n > b - 2) {
++a ;
b <<= 1 ;
}
bit_write(a, 0xfffffffe); /* lsb = 0 , other 31bit = 1 */
bit_write(a, (LONG)(n + 1 - b / 2));
}
void
write_color(c)
int c;
{
int a;
if ((a = search_col( c )) != -1) { /* color exist table ? */
bit_write(8, (LONG)( a+128 )) ; /* color table's index */
} else {
/* bit_write(16, (LONG)((unsigned int)c / 2));***********/
bit_write(16, (LONG)((unsigned int)c & 0x7fff));
}
}
int
search_col(c)
int c ;
{
int i ;
c &= 0x07fff ;
for ( i = 0 ; i < 128 ; i++ ) {
if ( table[i].color == c )
break ;
}
if ( i == 128 ) {
new_color( c ) ;
return( -1 ) ;
} else {
set_color( i ) ;
return( i ) ;
}
}
void
color_cash_init()
{
int i ;
for ( i = 0; i < 128; i++ ) {
table[i].color = 0;
table[i].prev = i + 1;
table[i].next = i - 1;
}
table[127].prev = 0;
table[0].next = 127;
color_p = 0;
}
void
new_color(c)
int c;
{
color_p = table[color_p].prev;
table[color_p].color = c;
}
void
set_color( idx )
int idx ;
{
if ( color_p != idx ) {
/* idx take off from table */
table[table[idx].prev].next = table[idx].next;
table[table[idx].next].prev = table[idx].prev;
/* idx set to new table point*/
table[table[color_p].prev].next = idx;
table[idx].prev = table[color_p].prev;
table[color_p].prev = idx;
table[idx].next = color_p;
color_p = idx;
}
}
/*
* size bits write for file
*
*/
void
bit_write(size, n)
SHORT size;
LONG n;
{
int i ;
int mask ;
mask = ( 1<<size )-1 ;
n &= mask;
n <<= ( 32-size ) ;
while (size > bit_length) {
for (i = 0; i < bit_length; i++) {
/* *buff_p = *buff_p + *buff_p + (n < 0);*/
*buff_p <<= 1;
*buff_p += ((n & 0x80000000) ? 1 : 0);
/* if n's msb is set then +1 */
/* n = n + n;
size = size - 1;*/
n <<= 1 ;
--size ;
}
buff_next_w();
}
for (i = 0; i < size; i++) {
/* *buff_p = *buff_p + *buff_p + (n < 0);*/
*buff_p <<= 1;
*buff_p += ((n & 0x80000000) ? 1 : 0);
/* if n's msb is set then +1 */
/* n = n + n;
bit_length = bit_length - 1;*/
n <<= 1 ;
bit_length-- ;
}
}
/*
* buff pointer inc. and write next buff
*/
void
buff_next_w()
{
if (--buff_length == 0) {
if (fwrite(buff,1, SIZE_OF_BUFF,fp) != SIZE_OF_BUFF) {
error("file write error buff_next_w");
}
buff_p = buff;
buff_length = SIZE_OF_BUFF;
} else {
++buff_p;
}
bit_length = 8;
}
void
buff_flush()
{
if (bit_length > 0) {
*buff_p <<= bit_length;
buff_next_w();
}
buff_length = SIZE_OF_BUFF - buff_length;
if (buff_length > 0) {
if (fwrite(buff,1, buff_length,fp) != buff_length){
error("file write error buff_flush");
}
}
}
void
error( s )
char *s ;
{
{ /* 本複文は,デバッグ用ダンプとして使用可 */
printf("%s", s);
/**
DISP_stringRect(buf, CI_Blue, CI_Gray);
MOU_waitClick(MouseLeftButton);
MOU_waitRelease(MouseLeftButton, &x, &y);
***/
}
exit(1);
}
int point( x,y )
int x,y ;
{
return( HS_pointm10( x,y )) ;
}
/*---------- Please rewrite --------------------------------------------
*
* c = point( x,y )
* dot get to graphic screen
*
* in
* x : screen X (0~SIZE_OF_X-1)
* y : screen Y (0~SIZE_OF_Y-1)
* out
* c : color code 16bit
* 0 : bright
* 1..5 : blue
* 6..10 : red
* 11..15: green
*/
/*---------- Please rewrite --------------------------------------------
*
* pset(x, y, c)
* dot set to graphic screen
*
* in
* x : screen X (0~SIZE_OF_X-1)
* y : screen Y (0~SIZE_OF_Y-1)
* c : color code 16bit
* 0 : bright
* 1..5 : blue
* 6..10 : red
* 11..15: green
*/
void pset( x,y,color )
int x,y,color ;
{
HS_psetm10( x,y,color ) ;
}